package com.cpos.cposcommon.util;

import com.qiniu.api.auth.AuthException;
import com.qiniu.api.auth.digest.Mac;
import com.qiniu.api.config.Config;
import com.qiniu.api.io.IoApi;
import com.qiniu.api.io.PutExtra;
import com.qiniu.api.io.PutRet;
import com.qiniu.api.rs.PutPolicy;
import netscape.javascript.JSObject;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.csource.common.MyException;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.apache.commons.net.ftp.FTPClient;
import com.qiniu.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.SocketException;
import java.util.Map;
import java.util.UUID;

/*
 *  @创建人  Leiwenlong
 *  @创建时间 2020/11/10
 *  @描述
 */
@RequestMapping("/file")
@Controller
public class FileUtil implements Serializable {

    @Value("${cpos.uploadPath}")
    private String UploadPath;

    @Value("${ftp.ipAddr}")
    private String ipAddr;

    @Value("${ftp.port}")
    private Integer port;

    @Value("${ftp.userName}")
    private String userName;

    @Value("${ftp.pwd}")
    private String pwd;

    @Value("${ftp.path}")
    private String path;

    @Value("${qnos.access_key}")
    private String accessKey;

    @Value("${qnos.secret_key}")
    private String secretKey;

    @Value("${qnos.backet_name}")
    private String backetName;

    Logger log =  LoggerFactory.getLogger(FileUtil.class);

    /*
    *  文件上传
    */
    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public CposResult Upload(HttpServletRequest request, HttpServletResponse response){

        CposResult cposResult = new CposResult();

        //获取请求体的Requst的文件流
        MultipartHttpServletRequest fileMap = (MultipartHttpServletRequest) request;


        if(!fileMap.equals(null)){
            Map<String, MultipartFile> forMap = fileMap.getFileMap();

            for (Map.Entry<String, MultipartFile> multipartFile : forMap.entrySet()) {
                MultipartFile file = multipartFile.getValue();
                //传入文件名
                String filename = file.getName();
                //获取文件的后缀名
                String extFileName = file.getOriginalFilename().toString().split("\\.")[1];

                //创建新文件名称
                String newName = System.currentTimeMillis()+"."+extFileName;

                //上传文件地址
                String upUrl = UploadPath+"//"+newName;

                File newFile = new File(upUrl);
                //判断文件夹是否存在
                if(!newFile.exists()){
                    newFile.mkdir();
                }

                try {
                    file.transferTo(newFile);
                } catch (IOException e) {
                    e.printStackTrace();
                    cposResult.setMsg("文件上传失败");
                    cposResult.setCode(500);
                    return cposResult;
                }
                cposResult.setData(upUrl);
            }
        }
        log.info("上传文件输出>> ->"+cposResult.toString());
        return cposResult;
    }

    /*
     *  文件下载
     *   改为RestFul风格传参
     */
    @RequestMapping(value = "/download/{fileName}",method = RequestMethod.GET)
    public HttpServletResponse download(HttpServletResponse response, @PathVariable("fileName") String fileName){
        CposResult cposResult = new CposResult();

        String path  = UploadPath +"//"+ fileName;

        try {
            if(!StringUtils.isEmpty(path)){

                // path是指欲下载的文件的路径。
                File file = new File(path);
                // 取得文件名。
                String filename = file.getName();
                // 取得文件的后缀名。
                String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
                // 以流的形式下载文件。
                InputStream fis = new BufferedInputStream(new FileInputStream(path));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
                response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
                response.addHeader("Content-Length", "" + file.length());
                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                response.setContentType("application/octet-stream");
                toClient.write(buffer);
                toClient.flush();
                toClient.close();
                log.info("文件下载成功");
            }else{
                log.error("文件路径为空");
            }

        } catch (IOException ex) {
            log.error("文件下载失败");
            ex.printStackTrace();
        }
        return response;
    }


    public FTPClient getFTPClient(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

                log.info("未连接到FTP，用户名或密码错误。");
                ftpClient.disconnect();
            } else {
                log.info("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            log.info("FTP的IP地址可能错误，请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }

    /*
     *  FTP文件上传
     */
    @RequestMapping(value = "/ftpUpload",method = RequestMethod.POST)
    public CposResult ftpUpload(HttpServletRequest request, HttpServletResponse response,InputStream input){
        CposResult cposResult = new CposResult();
        boolean result = false;
        FTPClient ftp = new FTPClient();

        try {
            int reply;
            ftp.connect(ipAddr, port);// 连接FTP服务器
            // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(userName, pwd);// 登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
           //     return result;
            }
            //切换到上传目录
            if (!ftp.changeWorkingDirectory("basePath"+path)) {
                //如果目录不存在创建目录
                String[] dirs = path.split("/");
                String tempPath = "basePath";
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            cposResult.setMsg("缺少路径");
                           return cposResult;
                        } else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件
            if (!ftp.storeFile("filename", input)) {
                cposResult.setMsg("缺少文件");
                return cposResult;
            }
            input.close();
            ftp.logout();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        cposResult.setMsg("上传成功");
        return cposResult;
    }

    /*
     *  FTP文件下载
     */
    @RequestMapping(value = "/ftpDownload",method = RequestMethod.POST)
    public CposResult ftpDownload(HttpServletRequest request, HttpServletResponse response,String ftpPath, String localPath,
        String fileName){
        CposResult cposResult = new CposResult();
        FTPClient ftpClient = null;

        try {
            ftpClient = getFTPClient(ipAddr, userName, pwd, port);
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory("ftpPath");

            File localFile = new File("localPath" + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            ftpClient.retrieveFile(fileName, os);
            os.close();
            ftpClient.logout();

        } catch (FileNotFoundException e) {
            log.error("没有找到" + ftpPath + "文件");
            e.printStackTrace();
        } catch (SocketException e) {
            log.error("连接FTP失败.");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件读取错误。");
            e.printStackTrace();
        }
        return cposResult;
    }

    /*
     *  FastDFS文件上传
     */
    @RequestMapping(value = "/fastDfsUpload",method = RequestMethod.POST)
    public CposResult fastDfsUpload(HttpServletRequest request, HttpServletResponse response){
        CposResult cposResult = new CposResult();

        try {
            // 2、创建一个 TrackerClient 对象。直接 new 一个。
            TrackerClient trackerClient = new TrackerClient();
            // 3、使用 TrackerClient 对象创建连接，获得一个 TrackerServer 对象。
            TrackerServer trackerServer = trackerClient.getConnection();
            // 4、创建一个 StorageServer 的引用，值为 null
            StorageServer storageServer = null;
            // 5、创建一个 StorageClient 对象，需要两个参数 TrackerServer 对象、StorageServer 的引用
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            // 6、使用 StorageClient 对象上传图片。
            //扩展名不带“.”
            String[] strings = storageClient.upload_file("D:\\work\\study\\ceshiImg\\1605274896176.png", "png", null);
            // 7、返回数组。包含组名和图片的路径。
            for (String string : strings) {
                System.out.println(string);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }

        return cposResult;
    }

    /*
     * FastDFS文件下载
     */
    @RequestMapping(value = "/fastDfsDownload",method = RequestMethod.POST)
    public CposResult fastDfsDownload(HttpServletRequest request, HttpServletResponse response){
        CposResult cposResult = new CposResult();

        return cposResult;
    }

    /*
     *  七牛云文件上传
     */
    @RequestMapping(value = "/qiNiuYunUpload",method = RequestMethod.POST)
    public CposResult qiNiuYunUpload(HttpServletRequest request, HttpServletResponse response){
        CposResult cposResult = new CposResult();

        //获取请求体的Requst的文件流
        MultipartHttpServletRequest fileMap = (MultipartHttpServletRequest) request;

        Config.ACCESS_KEY = accessKey;
        Config.SECRET_KEY = secretKey;
        Config.UP_HOST = "http://up-z2.qiniup.com";
        Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);
        // 请确保该bucket已经存在
        String bucketName = backetName;
        PutPolicy putPolicy = new PutPolicy(bucketName);
        String uptoken = null;


        if(!fileMap.equals(null)){
            Map<String, MultipartFile> forMap = fileMap.getFileMap();

            for (Map.Entry<String, MultipartFile> multipartFile : forMap.entrySet()) {
                MultipartFile file = multipartFile.getValue();
                //传入文件名
                String filename = file.getName();
                //获取文件的后缀名
                String extFileName = file.getOriginalFilename().toString().split("\\.")[1];

                //创建新文件名称
                String key = System.currentTimeMillis()+"."+extFileName;

                //上传文件地址
                String localFile = UploadPath+"//"+key;

                File newFile = new File(localFile);
                //判断文件夹是否存在
                if(!newFile.exists()){
                    newFile.mkdir();
                }

                try {
                    file.transferTo(newFile);

                    try {
                        uptoken = putPolicy.token(mac);
                    } catch (AuthException e) {
                        e.printStackTrace();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    PutExtra extra = new PutExtra();
                    PutRet ret = IoApi.putFile(uptoken, key, localFile, extra);
                    // http://qkg9ehwva.hn-bkt.clouddn.com
                    cposResult.setData(ret);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }


        return cposResult;
    }

    /*
     * 七牛云文件下载
     */
    @RequestMapping(value = "/qiNiuYunDownload",method = RequestMethod.POST)
    public CposResult qiNiuYunDownload(HttpServletRequest request, HttpServletResponse response){
        CposResult cposResult = new CposResult();

        return cposResult;
    }
}
